package org.example.reflect;

import org.example.reflect.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionDemo {

    public static void main(String[] args) {
        try {

            ExampleClass exampleClass = new ExampleClass("Test Value");

            Class<?> clazz = Class.forName("org.example.reflect.ExampleClass");

            // 反射类上的注解
            Annotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);
            if (classAnnotation != null) {
                System.out.println("Class annotation value: " + ((MyAnnotation) classAnnotation).value());
            }
            if(clazz.isAnnotationPresent(MyAnnotation.class)){
                System.out.println("Class annotation value: " + clazz.getAnnotation(MyAnnotation.class).value());
            }

            // 反射属性
            Field field = clazz.getDeclaredField("myField");
            field.setAccessible(true);
            System.out.println(field.get(exampleClass));
            Annotation fieldAnnotation = field.getAnnotation(MyFieldAnnotation.class);
            if (fieldAnnotation != null) {
                System.out.println("Field annotation value: " + ((MyFieldAnnotation) fieldAnnotation).value());
            }

            // 创建对象实例
            Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
            Object instance = constructor.newInstance("Test Value");

            // 反射方法
            Method method = clazz.getMethod("myMethod", String.class);
            Annotation methodAnnotation = method.getAnnotation(MyMethodAnnotation.class);
            if (methodAnnotation != null) {
                System.out.println("Method annotation value: " + ((MyMethodAnnotation) methodAnnotation).value());
            }

            // 调用方法
            method.setAccessible(true);
            Object result = method.invoke(instance, "Some Parameter");
            System.out.println("Method result: " + result);

            // 反射构造函数上的注解
            Annotation constructorAnnotation = constructor.getAnnotation(MyConstructorAnnotation.class);
            if (constructorAnnotation != null) {
                System.out.println("Constructor annotation value: " + ((MyConstructorAnnotation) constructorAnnotation).value());
            }

            // 反射方法参数上的注解
            Annotation[] parameterAnnotations = method.getParameterAnnotations()[0];
            for (Annotation pa : parameterAnnotations) {
                if (pa instanceof MyParameterAnnotation) {
                    System.out.println("Parameter annotation value: " + ((MyParameterAnnotation) pa).value());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}